/*
 * Copyright 2013 Agustina Martinez-Garcia

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */
package uk.ljmu.mulgaraifz.utilities;

import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

public class XmlTraverse {
    public static String[][] traverse(String xmlStr) {
	int i = 0, j = 0, k = 0;

	try {
	    Document myDoc = DocumentHelper.parseText(xmlStr);

	    // Get the root element of that file
	    Element rootEle = myDoc.getRootElement();

	    // Get all the children under this root into a list
	    List<?> rootChildren = rootEle.elements();

	    // Use an iterator to manage this list
	    Iterator<?> it = rootChildren.iterator();
	    // Ignore head element
	    it.next();
	    Element resultsChild = (Element) it.next();
	    Iterator<?> iterator = resultsChild.elements().iterator();

	    String[][] table = new String[resultsChild.elements().size()][2];
	    // Traverse through the list and process each child
	    while (iterator.hasNext()) {

		Element resultChild = (Element) iterator.next();

		// Check for the name of the child and do necessary processing
		// based on this
		if ((resultChild.getName()).equalsIgnoreCase("result")) {
		    List<?> bindingsList = resultChild.elements();

		    for (j = 0; j < bindingsList.size(); j++) {
			List<?> elemBind = ((Element) bindingsList.get(j))
				.elements();
			// Third level binding -> element literal or URI
			table[i][k] = ((Element) elemBind.get(0))
				.getStringValue();
			k++;
		    }
		} else
		    System.out.println("No Match!");
		i++;
		k = 0;
	    }
	    return table;
	} catch (Exception e) {
	    System.out.println("The xml file is not well-formed.");
	    System.out.println(e.getMessage());
	}
	return null;
    }

    /**
     * Generate a XML document object from an XML string
     * 
     * @param xmlStr
     *            string with the XML contents
     * @return xml document object from string
     */
    public static Document getDocument(String xmlStr) {
	Document myDoc;
	try {
	    if (xmlStr != null) {
		myDoc = DocumentHelper.parseText(xmlStr);
		return myDoc;
	    } else {
		return null;
	    }
	} catch (DocumentException ex) {
	    return null;
	}
    }

    /**
     * Method that returns an iterator over each "result" obtained from the
     * Mulgara graph
     * 
     * @param xmlContents
     *            Sparql-xml text as input
     * @return "\<results\>" iterator
     */
    public static Iterator<?> createSparqlXMLIterator(String xmlContents) {
	Document doc = XmlTraverse.getDocument(xmlContents);
	if (doc == null) {
	    return null;
	}
	Element root = doc.getRootElement(); // Element 'sparql'
	Element results = root.element("results");
	Iterator<?> iterator = null;
	try {
	    iterator = results.elements().iterator(); // Array of <result>
						      // element
	} catch (Exception ex) {
	    return null;
	}

	return iterator;
    }
    
    public static int numberOfElementsSparql(String xmlContents) {
    	Document doc = XmlTraverse.getDocument(xmlContents);
    	if (doc == null) {
    	    return 0;
    	}
    	Element root = doc.getRootElement(); // Element 'sparql'
    	Element results = root.element("results");
    	try {
    	    return results.elements().size();
    	} catch (Exception ex) {
    	    return 0;
    	}
        }

    /**
     * Method that returns an iterator over each "result" obtained from the
     * Mulgara graph
     * 
     * @param xmlContents
     *            Sparql-xml text as input
     * @return "<results>" iterator
     */
    public static Iterator<?> createRDFIterator(String xmlContents) {
	Document doc = getDocument(xmlContents);
	if (doc == null)
	    return null;
	Element root = doc.getRootElement(); // Element 'rdf:RDF'
	Iterator<?> iterator = root.elements().iterator(); // Array of
							   // <rdf:Description>
							   // element

	return iterator;
    }
}
